<template>
  <div :id="chartId" :class="className" :style="{ width, height }"></div>
</template>

<script>
import * as echarts from "echarts";

export default {
  name: "RingChart",
  props: {
    // 基础配置
    chartId: { type: String, default: "ring-chart" },
    className: { type: String, default: "ring-chart" },
    width: { type: String, default: "100%" },
    height: { type: String, default: "100%" },

    // 核心数据（只需传入单个数据）
    data: {
      type: Object,
      required: true,
      validator: (val) => val.name && val.value !== undefined, // 验证必须包含name和value
      description:
        "单个数据对象，格式: { name: '数据名称', value: 数值, itemStyle?: { color: '颜色' } }",
    },

    // 最大值（用于计算剩余比例）
    max: {
      type: Number,
      default: 100,
      description: "数据最大值，用于计算剩余比例",
    },

    // 图表配置
    title: { type: String, description: "主标题" },
    subTitle: { type: String, default: "暂无数据", description: "副标题" },
    remainingColor: {
      type: String,
      default: "#e5e5e5",
      description: "剩余比例的颜色",
    },
    labelShow: {
      type: Boolean,
      default: true,
      description: "是否显示中心文本",
    },
    radius: {
      type: Array,
      default: () => ["90%", "80%"],
      description: "环形内外半径，如['60%','80%']",
    },
    centerText: {
      type: Function,
      default: (value) => `${value}`,
      description: "中心文本格式化函数，默认显示原始值",
    },
    defaultColor: {
      type: String,
      default: "#409eff",
      description: "默认数据颜色",
    },
  },
  mounted() {
    this.initChart();
    window.addEventListener("resize", this.handleResize);
  },
  beforeUnmount() {
    window.removeEventListener("resize", this.handleResize);
    if (this.chart) this.chart.dispose(); // 销毁图表释放资源
  },
  watch: {
    data: {
      deep: true,
      handler() {
        this.updateChart();
      },
    },
    max() {
      this.updateChart();
    },
    title() {
      this.updateChart();
    },
    defaultColor() {
      this.updateChart();
    },
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el);
      this.updateChart();
    },

    updateChart() {
      if (!this.chart) return;
      this.chart.setOption(this.getChartOption());
    },

    handleResize() {
      this.chart?.resize();
    },

    // 生成完整数据（原始数据 + 剩余数据）
    getFullData() {
      const remainingValue = Math.max(0, this.max - this.data.value); // 确保剩余值非负
      return [
        // 原始数据
        // { ...this.data },
        {
          ...this.data,
          itemStyle: {
            ...this.data.itemStyle,
            color: this.data.itemStyle?.color || this.defaultColor,
          },
        },
        // 剩余数据（自动生成）
        {
          name: "剩余",
          value: remainingValue,
          itemStyle: { color: this.remainingColor },
          label: { show: false }, // 隐藏剩余数据的标签
          emphasis: { disabled: true }, // 鼠标 hover 时不高亮剩余部分
        },
      ];
    },

    getChartOption() {
      return {
        // title: ""
        //   ? {
        //       subtext: this.subTitle,
        //       left: "center",
        //       top: "30%",
        //       textStyle: { color: "#fff" },
        //       subtextStyle: { color: "#fff", fontSize: 14 },
        //     }
        //   : undefined,

        series: [
          {
            type: "pie",
            radius: this.radius,
            center: ["50%", "50%"],
            data: this.getFullData(),
            label: this.labelShow
              ? {
                  position: "center",
                  formatter: () => this.centerText(this.data.value), // 自定义中心文本
                  fontSize: 24,
                  fontWeight: "bold",
                  color: "#fff",
                  // textShadowColor: "red",
                  // textShadowBlur: 80,
                  // textShadowOffsetX: 0,
                  // textShadowOffsetY: 0,
                }
              : { show: false },
            labelLine: { show: false }, // 隐藏连接线
            avoidLabelOverlap: false, // 防止标签重叠
          },
        ],
      };
    },
  },
};
</script>

<style scoped>
.ring-chart {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}
</style>